home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / c.lqr / XC.C < prev   
Text File  |  1985-06-03  |  33KB  |  945 lines

  1.  
  2. /*************************************************************************/
  3. /*   9-26-83   Microsoft C 1.04  Conversion    WHR                       */
  4. /*     -  \t between line numbers and text to fix indenting problem.     */
  5. /*     -  added option -e for output to Epson in condensed print.        */
  6. /*     -  toupper() and isupper() are macros, not functions.             */
  7. /*     -  eliminate side effect in toupper(*++arg) in main().            */
  8. /*     -  change alloc() to malloc().                                    */
  9. /*     -  add #define NAMES that are not in stdio.h                      */
  10. /*     -  MS-C requires () in statement A?(c=B):(c=C)   error or not??   */
  11. /*                                                                       */
  12. /*   4-30-83   Computer Innovations C-86 1.31 Conversion    WHR          */
  13. /*     -  #include filename changed to allow a disk drive prefix, D:     */
  14. /*     -  convert if(fprintf(...) == ERROR) lst_err(); to fprintf(..);   */
  15. /*     -  convert if(fopen(...) == ERROR) statements to == NULL.         */
  16. /*     -  C86 requires () in statement A?(c=B):(c=C)    error or not??   */
  17. /*     -  remove getc() == ERROR check in fil_chr().                     */
  18. /*     -  convert file conventions from BDS C to C-86.                   */
  19. /*     -  comment out BDS unique statements, mark revised statements.    */
  20. /*        keep all BDS statements to document conversion effort.         */
  21. /*                                                                       */
  22. /**  4-19-83   BDS C Version file XC.CQ copied from Laurel RCPM    WHR   */
  23. /*************************************************************************/
  24. /*                                                         */
  25. /*    XC  -  A 'C' Concordance Utility                     */
  26. /*                                                         */
  27. /*    Version 1.0   January, 1982                          */
  28. /*                                                         */
  29. /*    Copyright (c) 1982 by Philip N. Hisley               */
  30. /*                                                         */
  31. /*    Released for non-commercial distribution only        */
  32. /*                                                         */
  33. /*    Abstract:                                            */
  34. /*                                                         */
  35. /*    'XC' is a cross-reference utility for 'C' programs.  */
  36. /*    Its has the ability to handle nested include files   */
  37. /*    to a depth of 8 levels and properly processes nested */
  38. /*    comments as supported by BDS C. Option flags support */
  39. /*    the following features:                              */
  40. /*                                                         */
  41. /*    - Routing of list output to disk                     */
  42. /*    - Cross-referencing of reserved words                */
  43. /*    - Processing of nested include files                 */
  44. /*    - Generation of listing only                         */
  45. /*                                                         */
  46. /*    Usage: xc <filename> <flag(s)>                       */
  47. /*                                                         */
  48. /*    Flags: -i            = Enable file inclusion         */
  49. /*           -l            = Generate listing only         */
  50. /*           -r            = Cross-ref reserved words      */
  51. /*           -o <filename> = Write output to named file    */
  52. /*                                                         */
  53. /*    Please report bugs/fixes/enhancements to:            */
  54. /*                                                         */
  55. /*            Philip N. Hisley                             */
  56. /*            548H Jamestown Court                         */
  57. /*            Edgewood, Maryland 21040                     */
  58. /*            (301) 679-4606                               */
  59. /*            Net Addr: PNH@MIT-AI                         */
  60. /*                                                         */
  61. /*                                                         */
  62. /***********************************************************/
  63.  
  64. /**BDS***  #include "bdscio.h"  */                          /* BDS C */
  65.  
  66. #include <stdio.h>                                            /* WHR */
  67. #include <ctype.h>                                            /* WHR */
  68.  
  69. #define  NULL       0
  70. #define  FALSE      0                                         /* WHR */
  71. #define  TRUE       1                                         /* WHR */
  72. #define  CPMEOF   0x1A                /* end of file */       /* WHR */
  73. #define  ERROR    (-1)                                        /* WHR */
  74.  
  75. #define  MAX_REF    5           /* maximum refs per ref-block */
  76.  
  77.  
  78.  
  79. #define  MAX_LEN    20          /* maximum identifier length  */
  80. #define  MAX_WRD   749          /* maximum number of identifiers */
  81. #define  MAX_ALPHA  53          /* maximum alpha chain heads */
  82. #define  REFS_PER_LINE  8       /* maximum refs per line */
  83. #define  LINES_PER_PAGE 60
  84. #define  FF 0x0C                 /* formfeed */
  85.  
  86. struct  id_blk {
  87.                  char  id_name[MAX_LEN];
  88.                  struct id_blk *alpha_lnk;
  89.                  struct rf_blk *top_lnk;
  90.                  struct rf_blk *lst_lnk;
  91.                } oneid;
  92.  
  93. struct  rf_blk {
  94.                  int  ref_item[MAX_REF];
  95.                  int  ref_cnt;
  96.                } onerf;
  97.  
  98. struct id_blk *id_vector[MAX_WRD];
  99.  
  100. struct alpha_hdr { struct id_blk *alpha_top;
  101.                    struct id_blk *alpha_lst;
  102.                  };
  103.  
  104. struct alpha_hdr alpha_vector[MAX_ALPHA];
  105.  
  106. int     linum;          /* line number */
  107. int     edtnum;         /* edit line number */
  108. int     fil_cnt;        /* active file index */
  109. int     wrd_cnt;        /* token count */
  110. int     pagno;          /* page number */
  111. int     id_cnt;         /* number of unique identifiers */
  112. int     rhsh_cnt;       /* number of conflict hits */
  113. int     filevl;         /* file level  */
  114. int     paglin;         /* page line counter */
  115. int     prt_ref;
  116. char    act_fil[MAX_LEN];
  117. char    lst_fil[MAX_LEN];
  118. char    gbl_fil[MAX_LEN];
  119. /*BDS**** char    l_buffer[BUFSIZ]; */                       /* BDS C */
  120. FILE   *l_buffer;                                            /*   WHR */
  121. int     i_flg,o_flg,r_flg,l_flg;
  122. int     debug;
  123. char    Epson[]  = "\x1B\x40\x0F\x1BQ\x84";                  /* WHR */
  124. int     e_flg;                                               /* WHR */
  125. /*-------------------------------------------*/
  126.  
  127. main(argc,argv)
  128.      int     argc;
  129.      char    **argv;
  130. {
  131.      char  *arg;
  132.      char *strcpy();
  133. /*** int  toupper();   ***/                  /* Microsoft C   macro */
  134.      char cc;                                /* Microsoft C */
  135.  
  136.      if (argc < 2) use_err();
  137.      i_flg=r_flg=o_flg=l_flg=FALSE;
  138.      debug = FALSE;
  139.      strcpy(gbl_fil,*++argv);
  140.      --argc;
  141.      if(gbl_fil[0] == '-')
  142.           use_err();
  143.      while(--argc != 0)
  144.      {    if(*(arg=*++argv) == '-')
  145.     /*****{    switch( toupper(*++arg) )     *** side effect in Microsoft C */
  146.           {    switch( cc=*++arg, toupper(cc) )              /* Microsoft C */
  147.                {   case 'I':  i_flg++;
  148.                               break;
  149.                    case 'R':  r_flg++;
  150.                               break;
  151.                    case 'L':  l_flg++;
  152.                               break;
  153.                    case 'O': {o_flg++;
  154.                               if(--argc == 0) use_err();
  155.                               strcpy(lst_fil,*++argv);
  156.                               if(lst_fil[0] == '-') use_err();
  157.                               if(debug) printf("lst_fil=>%s<",lst_fil);
  158.                               break;
  159.                              }
  160.                    case 'D':  debug++;
  161.                               break;
  162.                    case 'E':  e_flg++;                            /* WHR */
  163.                               o_flg++;
  164.                               strcpy(lst_fil,"LPT1:");
  165.                               break;
  166.                    default:   use_err();
  167.                }
  168.           }
  169.      else use_err();
  170.      }
  171.      if(debug) printf("\ni_flg=%d, r_flg=%d, l_flg=%d", i_flg,r_flg,l_flg);
  172.      if(debug) printf("\no_flg=%d, debug=%d", o_flg,debug);
  173.      if (o_flg)
  174. /*BDS{    if ( (l_buffer = fopen(lst_fil,"w")) == ERROR) ** output file **BDS*/
  175.  
  176.      {    if ( (l_buffer = fopen(lst_fil,"w")) == NULL)   /*** output file ***/
  177.           {    printf("ERROR: Unable to create list file - %s\n",lst_fil);
  178.                exit(0);
  179.           }
  180.           printf("\nXC ....... 'C' Concordance Utility  v1.0\n");
  181.           printf("    Microsoft C 1.04,  Conversion 9-26-83\n\n");  /* WHR */
  182.           if (e_flg) fprintf(l_buffer,"%s",Epson);
  183.      }
  184.                                                                      /* WHR */
  185.   /**BDS***   _allocp = NULL;**/ /* initialize memory allocation pointer */
  186.      prt_ref = FALSE;
  187.      for(linum=0;linum < MAX_WRD;linum++) {
  188.           id_vector[linum] = NULL;
  189.      }
  190.      for(linum=0;linum < MAX_ALPHA;linum++)
  191.      {
  192.           alpha_vector[linum].alpha_top =
  193.                alpha_vector[linum].alpha_lst = NULL;
  194.      }
  195.      fil_cnt = wrd_cnt = linum = 0;
  196.      filevl=paglin=pagno=edtnum=0;
  197.      id_cnt=rhsh_cnt=0;
  198.      proc_file(gbl_fil);
  199.      if(!l_flg) {
  200.          prnt_tbl();
  201.          printf("\nAllowable Symbols: %d\n",MAX_WRD);
  202.          printf("Unique    Symbols: %d\n",id_cnt);
  203.      }
  204.      if(o_flg) {
  205.           nl();
  206.           fprintf(l_buffer,"\nAllowable Symbols: %d\n",MAX_WRD);   /* WHR */
  207.           fprintf(l_buffer,"Unique    Symbols: %d\n",id_cnt);      /* WHR */
  208.           fprintf(l_buffer,"%c%c",FF,CPMEOF);                      /* WHR */
  209.           /*BDSif(fprintf(l_buffer,"%c",CPMEOF) == ERROR) lst_err();  **/
  210.           fflush(l_buffer);
  211.           fclose(l_buffer);
  212.      }
  213. }/*main.
  214. ----------------------------------------*/
  215.  
  216. strcmp(s,t)
  217.      char s[], t[];
  218. {
  219.      int i;
  220.      i=0;
  221.      while(s[i] == t[i])
  222.           if(s[i++] == '\0') return (0);
  223.      return (s[i]-t[i]);
  224. }/*strcmp.
  225. ----------------------------------------*/
  226.  
  227.  
  228. char *strcpy(s1,s2)
  229.      char *s1, *s2;
  230. {
  231.      char  *temp;
  232.      temp=s1;
  233.      while (*s1++ = *s2++);
  234.      return (temp);
  235. }/*strcpy.
  236. ----------------------------------*/
  237.  
  238.  
  239. lst_err()
  240. {
  241.      printf("\nERROR: Write error on list output file - %s\n",
  242.      lst_fil);
  243.      exit(0);
  244. }/*lst_err.
  245. -----------------------------------*/
  246.  
  247.  
  248. use_err()
  249. {
  250.      printf("\nERROR: Invalid parameter specification\n\n");
  251.      printf("Usage: xc <filename> <flag(s)>\n\n");
  252.      printf("Flags: -i             = Enable file inclusion\n");
  253.      printf("       -l             = Generate listing only\n");
  254.      printf("       -r             = Cross-reference reserved words\n");
  255.      printf("       -o <filename>  = Write output to named file\n");
  256.      exit(0);
  257. }/*use_err.
  258. -------------------------------------------*/
  259.  
  260.  
  261. proc_file(filnam)
  262.      char    *filnam;
  263.  
  264. {
  265.      FILE  *buffer;        /* allocated buffer pointer */           /* WHR */
  266.   /***BDS***   char  *buffer;        * allocated buffer pointer */
  267.   /***BDS***   char  *sav_buffer;    * saved alloc buffer pointer */
  268.      char  token[MAX_LEN]; /* token buffer */
  269.      int   eof_flg;        /* end-of-file indicator */
  270.      int   tok_len;        /* token length */
  271.      int   incnum;         /* included line number */
  272.      char *strcpy();
  273.  
  274.      strcpy(act_fil,filnam);
  275.   /*   BDS C stuff                                               * WHR *
  276.   **   if ((sav_buffer = buffer =  alloc(BUFSIZ)) == 0) {
  277.   **       printf("\nERROR: Unable to allocate file buffer for %s\n",filnam);
  278.   **       exit(0);
  279.   **  }
  280.   **  if (fopen(filnam,buffer)) == ERROR)   *** input file ***
  281.   */
  282.      if ((buffer = fopen(filnam,"r")) == NULL)  /*** input file ***/ /* WHR */
  283.      {    printf("\nERROR: Unable to open input file: %s\n",filnam);
  284.           exit(0);
  285.      }
  286.      if(filevl++ == 0) prt_hdr();
  287.      eof_flg = FALSE;
  288.  
  289.      do {
  290.           if(get_token(buffer,token,&tok_len,&eof_flg,0))
  291.           {    if (debug) printf("\ntoken: %s   length: %d\n",token,&tok_len);
  292.                if (chk_token(token))
  293.                {
  294.                      /* #include processing changed to accept drive:   WHR */
  295.                     if (strcmp(token,"#include") == 0)
  296.                     {    if (get_token(buffer,token,&tok_len,&eof_flg,1))
  297.                          {    if (debug) printf("\ntoken: %s   length: %d\n",
  298.                                                   token,&tok_len);
  299.                               if (!i_flg) continue;
  300.                               else
  301.                               {    incnum=edtnum;
  302.                                    edtnum=0;
  303.                                    nl();
  304.                                    proc_file(token);
  305.                                    edtnum=incnum;
  306.                                    strcpy(act_fil,filnam);
  307.  
  308.                                    continue;
  309.                               }
  310.                          }
  311.                     }
  312.                     put_token(token,linum);
  313.                }
  314.           }
  315.      } while (!eof_flg);
  316.  
  317.      filevl -= 1;
  318.      fclose(buffer);
  319.  /***    free(sav_buffer);  */
  320. }/*proc_file.
  321. -------------------------------------------*/
  322.  
  323. get_token(g_buffer,g_token,g_toklen,g_eoflg,g_flg)
  324.      FILE    *g_buffer;
  325.      char    *g_token;
  326.      int     *g_toklen;
  327.      int     *g_eoflg;
  328.      int     g_flg;
  329.  
  330.     /*
  331.      *   'getoken' returns the next valid identifier or
  332.      *   reserved word from a given file along with the
  333.      *   character length of the token and an end-of-file
  334.      *   indicator
  335.      *
  336.      */
  337.  
  338. {
  339.      int     c;
  340.      char    *h_token;
  341.      char    tmpchr;
  342.      char    tmpchr2;                 /* WHR fix for B:filename.ext */
  343.  
  344.      h_token = g_token;
  345.  
  346.  gtk:                          /* top of loop, get new token */
  347.      *g_toklen = 0;
  348.      g_token = h_token;
  349.  
  350.     /*
  351.      *  Scan and discard any characters until an alphabetic or
  352.      *  '_' (underscore) character is encountered or an end-of-file
  353.      *  condition occurs
  354.      */
  355.  
  356.      while(  (!isalpha(*g_token = rdchr(g_buffer,g_eoflg,g_flg)))
  357.              &&  !*g_eoflg      &&  *g_token != '_'
  358.              && *g_token != '0' &&  *g_token != '#' );
  359.      if(*g_eoflg) return(FALSE);
  360.  
  361.      *g_toklen += 1;
  362.  
  363.     /*
  364.      *   Scan and collect identified alpanumeric token until
  365.      *   a non-alphanumeric character is encountered or and
  366.      *   end-of-file condition occurs
  367.      */
  368.  
  369.      if(g_flg) {
  370.           tmpchr  = '.';
  371.           tmpchr2 = ':';                   /* WHR fix for B:filename.ext */
  372.      }
  373.      else {
  374.           tmpchr  = '_';
  375.           tmpchr2 = '_';                   /* WHR fix for B:filename.ext */
  376.      }
  377.      while( (isalpha(c=rdchr(g_buffer,g_eoflg,g_flg)) ||
  378.             isdigit(c) || c == '_' || c == tmpchr || c == tmpchr2)
  379.             && !*g_eoflg)                  /* WHR fix for B:filename.ext */
  380.      {    if(*g_toklen < MAX_LEN)
  381.           {    *++g_token = c;
  382.                *g_toklen += 1;
  383.           }
  384.      }
  385.  
  386.  
  387.     /*
  388.      *      Check to see if a numeric hex or octal constant has
  389.      *      been encountered ... if so dump it and try again
  390.      */
  391.  
  392.  
  393.      if (*h_token == '0') goto gtk;
  394.  
  395.  
  396.     /*
  397.      *      Tack a NULL character onto the end of the token
  398.      */
  399.  
  400.      *++g_token = NULL;
  401.  
  402.     /*
  403.      *      Screen out all #token strings except #include
  404.      */
  405.  
  406.      if (*h_token == '#' && strcmp(h_token,"#include")) goto gtk;
  407.  
  408.      return (TRUE);
  409. }/*get_token.
  410. -----------------------------------------*/
  411.  
  412. fil_chr(f_buffer,f_eof)
  413.      FILE *f_buffer;
  414.      int *f_eof;
  415. {
  416.      int fc;
  417.      fc=getc(f_buffer);
  418. /*   if(fc == ERROR)       **** BDS stuff ****                       ** WHR **
  419. **   {    printf("\nERROR: Error while processing input file - %s\n",
  420. **        act_fil);
  421. **        exit(0);
  422. **   }
  423. */
  424.      if (fc == CPMEOF || fc == EOF) {
  425.           *f_eof = TRUE;
  426.           fc = NULL;
  427.      }
  428.      return(fc);
  429. }/*fil_chr.
  430. ----------------------------------------*/
  431.  
  432. rdchr(r_buffer,r_eoflg,rd_flg)
  433.      int     *r_eoflg;
  434.      FILE    *r_buffer;
  435.      int     rd_flg;
  436.  
  437. /*
  438.         'rdchr' returns the next valid character in a file
  439.         and an end-of-file indicator. A valid character is
  440.         defined as any which does not appear in either a
  441.         commented or a quoted string ... 'rdchr' will correctly
  442.         handle comment tokens which appear within a quoted
  443.         string
  444. */
  445.  
  446. {
  447.      int     c;
  448.      int     q_flg;          /* double quoted string flag */
  449.      int     q1_flg;         /* single quoted string flag */
  450.      int     cs_flg;         /* comment start flag */
  451.      int     ce_flg;         /* comment end flag */
  452.      int     c_cnt;          /* comment nesting level */
  453.      int     t_flg;          /* transparency flag */
  454.  
  455.      q_flg = FALSE;
  456.      q1_flg = FALSE;
  457.      cs_flg = FALSE;
  458.      ce_flg = FALSE;
  459.      t_flg = FALSE;
  460.      c_cnt  = 0;
  461.  
  462. rch:
  463.  
  464.  
  465.     /*
  466.      *   Fetch character from file
  467.      */
  468.  
  469.      c = fil_chr(r_buffer,r_eoflg);
  470.  
  471.      if (*r_eoflg) return(c);   /* EOF encountered */
  472.      if (c == '\n')
  473.            nl();
  474.      else
  475.           if (o_flg)
  476.                fprintf(l_buffer,"%c",c);                        /* WHR */
  477.       /* BDSC  {    if (fprintf(l_buffer,"%c",c) == ERROR)      ** WHR **
  478.        *             lst_err();
  479.        *       }
  480.        */
  481.           else
  482.                printf("%c",c);
  483.  
  484.      if (rd_flg) return(c);
  485.  
  486.      if (t_flg) {
  487.           t_flg = !t_flg;
  488.           goto rch;
  489.      }
  490.  
  491.      if (c == '\\') {
  492.           t_flg = TRUE;
  493.           goto rch;
  494.      }
  495.         /*
  496.         If the character is not part of a quoted string
  497.         check for and process commented strings...
  498.         nested comments are handled correctly but unbalanced
  499.         comments are not ... the assumption is made that
  500.         the syntax of the program being xref'd is correct
  501.         */
  502.  
  503.      if (!q_flg  &&  !q1_flg) {
  504.           if (c == '*'  &&  c_cnt  &&  !cs_flg) {
  505.                ce_flg = TRUE;
  506.                goto rch;
  507.           }
  508.           if (c == '/'  &&  ce_flg) {
  509.                c_cnt -= 1;
  510.                ce_flg = FALSE;
  511.                goto rch;
  512.           }
  513.           ce_flg = FALSE;
  514.           if (c == '/') {
  515.                cs_flg = TRUE;
  516.                goto rch;
  517.           }
  518.           if (c == '*'  &&  cs_flg) {
  519.                c_cnt += 1;
  520.                cs_flg = FALSE;
  521.                goto rch;
  522.           }
  523.           cs_flg = FALSE;
  524.  
  525.           if (c_cnt) goto rch;
  526.      }
  527.  
  528.         /*
  529.         Check for and process quoted strings
  530.         */
  531.  
  532.      if ( c == '"'  &&  !q1_flg) {      /* toggle quote flag */
  533.           q_flg =  !q_flg;
  534.           if(debug) printf("\nq_flg toggled to: %d\n" ,q_flg);
  535.           goto rch;
  536.      }
  537.      if (q_flg) goto rch;
  538.  
  539.      if (c == '\'') {        /* toggle quote flag */
  540.           q1_flg = !q1_flg;
  541.           if(debug) printf("\nq1_flg toggled to: %d\n" ,q1_flg);
  542.           goto rch;
  543.      }
  544.      if (q1_flg) goto rch;
  545.  
  546.         /*
  547.         Valid character ... return to caller
  548.         */
  549.  
  550.      return (c);
  551. }/*rdchr.
  552. -----------------------------------------------*/
  553.  
  554.  
  555. chk_token(c_token)
  556.      char    *c_token;
  557. {
  558.      char  u_token[MAX_LEN];
  559.      int   i;
  560.  
  561.      {
  562.       if (r_flg) return(TRUE);
  563.       i = 0;
  564.       do { u_token[i] = toupper(c_token[i]);
  565.       } while (c_token[i++] != NULL);
  566.  
  567.       switch(u_token[0]) {
  568.         case 'A': if (strcmp(u_token,"AUTO") == 0) return(FALSE);
  569.                   break;
  570.         case 'B': if (strcmp(u_token,"BREAK") == 0) return(FALSE);
  571.                   break;
  572.         case 'C': if (strcmp(u_token,"CHAR") == 0) return (FALSE);
  573.                   if (strcmp(u_token,"CONTINUE") == 0) return (FALSE);
  574.                   if (strcmp(u_token,"CASE") == 0) return (FALSE);
  575.                   break;
  576.  
  577.         case 'D': if(strcmp(u_token,"DOUBLE") == 0) return(FALSE);
  578.                   if(strcmp(u_token,"DO") == 0) return(FALSE);
  579.                   if(strcmp(u_token,"DEFAULT") == 0) return(FALSE);
  580.                   break;
  581.         case 'E': if(strcmp(u_token,"EXTERN") == 0) return(FALSE);
  582.                   if(strcmp(u_token,"ELSE") == 0) return(FALSE);
  583.                   if(strcmp(u_token,"ENTRY") == 0) return(FALSE);
  584.                   break;
  585.         case 'F': if(strcmp(u_token,"FLOAT") == 0) return(FALSE);
  586.                   if(strcmp(u_token,"FOR") == 0) return(FALSE);
  587.                   break;
  588.         case 'G': if(strcmp(u_token,"GOTO") == 0) return(FALSE);
  589.                   break;
  590.         case 'I': if(strcmp(u_token,"INT") == 0) return(FALSE);
  591.                   if(strcmp(u_token,"IF") == 0) return(FALSE);
  592.                   break;
  593.         case 'L': if(strcmp(u_token,"LONG") == 0) return(FALSE);
  594.                   break;
  595.         case 'R': if(strcmp(u_token,"RETURN") == 0) return(FALSE);
  596.                   if(strcmp(u_token,"REGISTER") == 0) return(FALSE);
  597.                   break;
  598.         case 'S': if(strcmp(u_token,"STRUCT") == 0) return(FALSE);
  599.                   if(strcmp(u_token,"SHORT") == 0) return(FALSE);
  600.                   if(strcmp(u_token,"STATIC") == 0) return(FALSE);
  601.                   if(strcmp(u_token,"SIZEOF") == 0) return(FALSE);
  602.                   if(strcmp(u_token,"SWITCH") == 0) return(FALSE);
  603.                   break;
  604.         case 'T': if(strcmp(u_token,"TYPEDEF") == 0) return(FALSE);
  605.                   break;
  606.         case 'U': if(strcmp(u_token,"UNION") == 0) return(FALSE);
  607.                   if(strcmp(u_token,"UNSIGNED") == 0) return(FALSE);
  608.                   break;
  609.         case 'W': if(strcmp(u_token,"WHILE") == 0) return(FALSE);
  610.                   break; }
  611.         }
  612.   return (TRUE);
  613. }/*chk_token.
  614. ---------------------------------------------*/
  615.  
  616.  
  617.   /*
  618.    *    Install parsed token and line reference in linked structure
  619.    */
  620.  
  621. put_token(p_token,p_ref)
  622.      char *p_token;
  623.      int  p_ref;
  624. {
  625.      int  hsh_index;
  626.      int  i;
  627.      int  j;
  628.      int  d;
  629.      int  found;
  630.      struct id_blk *idptr;
  631.      struct rf_blk *rfptr;
  632.      struct id_blk *alloc_id();
  633.      struct rf_blk *alloc_rf();
  634.      struct rf_blk *add_rf();
  635.  
  636.      if (l_flg) return;
  637.      j=0;
  638.      for (i=0; p_token[i] != NULL; i++)  /* Hashing algorithm is far from */
  639.      {                                   /* optimal but is adequate for a */
  640.          j = j * 10 + p_token[i];        /* memory-bound index vector!    */
  641.      }
  642.      hsh_index = abs(j) % MAX_WRD;
  643.  
  644.      found = FALSE;
  645.      d = 1;
  646.      do
  647.      {    idptr = id_vector[hsh_index];
  648.           if (idptr == NULL)
  649.           {    id_cnt++;
  650.                idptr = id_vector[hsh_index] = alloc_id(p_token);
  651.                chain_alpha(idptr,p_token);
  652.                idptr->top_lnk = idptr->lst_lnk = alloc_rf(p_ref);
  653.                found = TRUE;
  654.           }
  655.           else
  656.           if (strcmp(p_token,idptr->id_name) == 0)
  657.           {    idptr->lst_lnk = add_rf(idptr->lst_lnk,p_ref);
  658.                found = TRUE;
  659.           }
  660.           else
  661.           {    hsh_index += d;
  662.                d += 2;
  663.                rhsh_cnt++;
  664.                if (hsh_index >= MAX_WRD)
  665.                     hsh_index -= MAX_WRD;
  666.                if (d == MAX_WRD)
  667.                {    printf("\nERROR: Symbol table overflow\n");
  668.                     exit(0);
  669.                }
  670.           }
  671.      } while (!found);
  672. }/*put_token.
  673. --------------------------------------------*/
  674.  
  675.  
  676. chain_alpha(ca_ptr,ca_token)
  677.      struct id_blk *ca_ptr;
  678.      char  *ca_token;
  679. {
  680.      char  c;
  681.      int   f;
  682.      struct id_blk *cur_ptr;
  683.      struct id_blk *lst_ptr;
  684. /*** int isupper();   ****/            /** Microsoft C   macro **/
  685.  
  686.  
  687.      c = ca_token[0];
  688.      if (c == '_')  c = 0;
  689.      else
  690.      /**  isupper(c) ? c=1+((c-'A')*2) : c=2+((c-'a')*2) ;     error or not??
  691.       **  A good one for the puzzle book! Is the () required around (c=..)?
  692.       **  C86 and Microsoft C both req the ()'s, BDS C did not.
  693.       **  Is it required because = has lower precedence than ?: ????
  694.       **/
  695.           isupper(c) ? (c=1+((c-'A')*2)) : (c=2+((c-'a')*2)) ;
  696.  
  697.      if(alpha_vector[c].alpha_top == NULL)
  698.      {    alpha_vector[c].alpha_top =
  699.                   alpha_vector[c].alpha_lst = ca_ptr;
  700.           ca_ptr->alpha_lnk = NULL;
  701.           return;
  702.      }
  703.  
  704.     /*  check to see if new id_blk should be inserted between
  705.      *  the alpha_vector header block and the first id_blk in
  706.      *  the current alpha chain
  707.      */
  708.  
  709.      if(strcmp(alpha_vector[c].alpha_top->id_name,ca_token) >0)
  710.      {    ca_ptr->alpha_lnk=alpha_vector[c].alpha_top;
  711.           alpha_vector[c].alpha_top=ca_ptr;
  712.           return;
  713.      }
  714.  
  715.      if(strcmp(alpha_vector[c].alpha_lst->id_name,ca_token) < 0)
  716.      {    alpha_vector[c].alpha_lst->alpha_lnk = ca_ptr;
  717.           ca_ptr->alpha_lnk = NULL;
  718.           alpha_vector[c].alpha_lst=ca_ptr;
  719.           return;
  720.      }
  721.  
  722.      cur_ptr = alpha_vector[c].alpha_top;
  723.      while(strcmp(cur_ptr->id_name,ca_token) < 0)
  724.      {    lst_ptr = cur_ptr;
  725.           cur_ptr = lst_ptr->alpha_lnk;
  726.      }
  727.  
  728.      lst_ptr->alpha_lnk = ca_ptr;
  729.      ca_ptr->alpha_lnk = cur_ptr;
  730.      return;
  731. }/*chain_alpha.
  732. -----------------------------------------*/
  733.  
  734.  
  735.  
  736.  
  737.      struct id_blk
  738. *alloc_id(aid_token)
  739.      char  *aid_token;
  740. {
  741.      int  ai;
  742.      struct id_blk *aid_ptr;
  743.      char *malloc();                                         /* Microsoft C */
  744.  
  745. /*** if((aid_ptr =  alloc(sizeof(oneid))) == 0) { ***/       /* Microsoft C */
  746.      if((aid_ptr = (struct id_blk *) malloc(sizeof(oneid))) == 0) { /* MS C */
  747.  
  748.           printf("\nERROR: Unable to allocate identifier block\n");
  749.           exit(0);
  750.      }
  751.      ai=0;
  752.      do {
  753.           aid_ptr->id_name[ai] = aid_token[ai];
  754.      } while (aid_token[ai++] != NULL);
  755.      return (aid_ptr);
  756. }/*id_blk.
  757. -----------------------------------------*/
  758.  
  759.      struct rf_blk
  760. *alloc_rf(arf_ref)
  761.      int  arf_ref;
  762. {
  763.     int ri;
  764.     struct rf_blk *arf_ptr;
  765.     char * malloc();                                   /* Microsoft C */
  766.  
  767. /** if((arf_ptr = alloc(sizeof(onerf))) == 0) { **/    /* Microsoft C */
  768.     if((arf_ptr = (struct rf_blk *) malloc(sizeof(onerf))) == 0) { /* MS C */
  769.          printf("\nERROR: Unable to allocate reference block\n");
  770.          exit(0);
  771.     }
  772.     arf_ptr->ref_item[0] = arf_ref;
  773.     arf_ptr->ref_cnt = 1;
  774.     for (ri=1;ri<MAX_REF;ri++)
  775.           arf_ptr->ref_item[ri] = NULL;
  776.     return (arf_ptr);
  777. }/*alloc_rf.
  778. ------------------------------------------*/
  779.  
  780.  
  781.      struct rf_blk
  782. *add_rf(adr_ptr,adr_ref)
  783.  
  784.      struct rf_blk *adr_ptr;
  785.      int adr_ref;
  786. {
  787.      struct rf_blk *tmp_ptr;
  788.  
  789.      tmp_ptr = adr_ptr;
  790.      if(adr_ptr->ref_cnt == MAX_REF) {
  791.      /*** tmp_ptr = adr_ptr->ref_cnt = alloc_rf(adr_ref);    Microsoft C **/
  792.           adr_ptr->ref_cnt = alloc_rf(adr_ref);           /* Microsoft C **/
  793.           tmp_ptr = (struct rf_blk *) adr_ptr->ref_cnt;   /* Microsoft C **/
  794.      }
  795.      else
  796.      {    adr_ptr->ref_item[adr_ptr->ref_cnt++] = adr_ref;
  797.      }
  798.      return (tmp_ptr);
  799. }/*rf_blk.
  800. ------------------------------------------*/
  801.  
  802. prnt_tbl()
  803. {
  804.      int prf_cnt;
  805.      int pti;
  806.      int pref;
  807.      int lin_cnt;
  808.      struct id_blk *pid_ptr;
  809.      struct rf_blk *ptb_ptr;
  810.  
  811.      prt_ref = TRUE;
  812.      prt_hdr();
  813.      for (pti=0;pti<MAX_ALPHA;pti++)
  814.      {    if ((pid_ptr = alpha_vector[pti].alpha_top) != NULL)
  815.           {    do
  816.                {    if(o_flg)
  817.                          fprintf(l_buffer,"%-14.13s: ",pid_ptr->id_name);/*WHR*/
  818.            /* BDSC  {    if(fprintf(l_buffer,"%-14.13s: ",
  819.             *                       pid_ptr->id_name) == ERROR)
  820.             *            lst_err();
  821.             *       }
  822.             */
  823.                     else
  824.                          printf("%-14.13s: ",pid_ptr->id_name);
  825.                     ptb_ptr=pid_ptr->top_lnk;
  826.                     lin_cnt=prf_cnt=0;
  827.                     do
  828.                     {    if(prf_cnt == MAX_REF)
  829.                          {    prf_cnt=0;
  830.                          /*** ptb_ptr = ptb_ptr->ref_cnt;  Microsoft C **/
  831.                               ptb_ptr = (struct rf_blk *)ptb_ptr->ref_cnt;
  832.                          }
  833.                          if(ptb_ptr > MAX_REF)
  834.                          {
  835.                               if((pref=ptb_ptr->ref_item[prf_cnt++]) != 0)
  836.                               {    if(o_flg)
  837.                                      fprintf(l_buffer,"%-4d  ",pref); /*WHR*/
  838.                           /* BDSC  { if(fprintf(l_buffer,"%-4d  ",pref)
  839.                            *                     == ERROR) lst_err();
  840.                            *       }
  841.                            */
  842.                                    else
  843.                                         printf("%-4d  ",pref);
  844.                                    if (++lin_cnt == REFS_PER_LINE)
  845.                                    {    nl();
  846.                                         if(o_flg)
  847.                                            fprintf(l_buffer,"\t\t");   /*WHR*/
  848.                             /* BDSC     {  if(fprintf(l_buffer,"\t\t")
  849.                              *                   == ERROR) lst_err();
  850.                              *          }
  851.                              */
  852.                                         else
  853.                                              printf("\t\t");
  854.                                         lin_cnt=0;
  855.                                    }
  856.                               }
  857.                          }
  858.                          else pref=0;
  859.                     } while (pref);
  860.                     if (lin_cnt = 0)
  861.                          nl();
  862.                     else
  863.                     {    nl();    /**  nl(); ***single space****/
  864.                     }
  865.                } while ((pid_ptr=pid_ptr->alpha_lnk) != NULL);
  866.           }
  867.      }
  868. }/*prnt_tbl.
  869. ---------------------------------------*/
  870.  
  871.  
  872. prt_hdr()
  873.  
  874. {
  875.      if (pagno++ != 0)
  876.      if(o_flg)
  877.           fprintf(l_buffer,"%c",FF);                          /* WHR */
  878. /*BDS{    if(fprintf(l_buffer,"%c",FF) == ERROR) lst_err();
  879.  *   }
  880.  */
  881.      else printf("%c",FF);
  882.  
  883.      if(o_flg)
  884.           fprintf(l_buffer,
  885.                     "XC ... 'C' Concordance Utility : %s\t\t\t\t Page %d",
  886.                     gbl_fil,pagno);                            /* WHR */
  887. /*BDS{    if(fprintf(l_buffer,
  888.  *                  "XC ... 'C' Concordance Utility : %s\t\t\t\t Page %d",
  889.  *                  gbl_fil,pagno) == ERROR) lst_err();
  890.  *   }
  891.  */
  892.      else
  893.           printf("XC ... 'C' Concordance Utility : %s\t\t\t\t Page %d",
  894.                   gbl_fil,pagno);
  895.      if (o_flg)
  896.           fprintf(l_buffer,"\n\n");                               /* WHR */
  897. /*BDS{    if(fprintf(l_buffer,"\n\n") == ERROR) lst_err();
  898.  *   }
  899.  */
  900.      else     printf("\n\n");
  901.  
  902.      nl();
  903.      paglin =3;
  904.      return;
  905. }/*prt_hdr.
  906. --------------------------------------*/
  907.  
  908.  
  909. nl()
  910.  
  911. {
  912.      if (o_flg)
  913.           fprintf(l_buffer,"\n");                                /* WHR */
  914. /*BDS{    if(fprintf(l_buffer,"\n") == ERROR) lst_err();
  915.  *   }
  916.  */
  917.      else
  918.           printf("\n");
  919.  
  920.      if (++paglin == LINES_PER_PAGE) prt_hdr();
  921.      else
  922.           if(!prt_ref)
  923.           {    if(o_flg)
  924.                     fprintf(l_buffer,"%-4d %4d:\t",
  925.                                 ++linum,++edtnum);               /* WHR */
  926. /*BDS          {    if (fprintf(l_buffer,"%-4d %4d:  ",
  927.  *                              ++linum,++edtnum) == ERROR)
  928.  *                       lst_err();
  929.  *             }
  930.  */
  931.                else
  932.                     printf("%-4d %4d:\t",++linum,++edtnum);
  933.  
  934.                if(o_flg)
  935.                     if(linum % 60 == 1)
  936.                          printf("\n<%d>\t",linum);
  937.                     else
  938.                          printf(".");
  939.           }
  940.      return;
  941. }/*nl.
  942. -------------------------------------------*/
  943. /*============= end of file xc.c ==========================*/
  944.  
  945.